<?php


/*
 * Created on 15/05/2006
 *
 * @author Rafael Guerrero
 */
class NetworkHandler extends BaseHandler {
	/**
	 * @type MTrans
	 */
	private $currTrans;

	// ----------------------------------------
	// Props Methods
	// ----------------------------------------
	/**
	 * @type MNetwork
	 */
	private $network;

	/**
	 * @type array
	 */
	private $nodesByName;

	// ----------------------------------------

	public function __construct() {
		parent :: __construct();
		$this->network = BaseHandler :: $session->create('MNetwork');
	}

	// ----------------------------------------
	// Handler Methods
	// ----------------------------------------

	private function networkBeg(& $parser, $tag, $attributes) {
		$this->network->setName($attributes['name']);
	}

	private function placeBeg(& $parser, $tag, $attributes) {
		$place = & BaseHandler :: $session->create('MPlace');

		$place->setName($attributes['name']);
		$place->setTokens($attributes['tokens']);

		$placeList = & $this->network->getPlaceList();
		$placeList[] = $place;

		if (isset ($this->nodesByName[$place->getName()])) {
			throw new Exception("Duplicated name " + place . getName());
		}

		$this->nodesByName[$place->getName()] = & $place;

	}

	private function transBeg(& $parser, $tag, $attributes) {
		

		$this->currTrans = & BaseHandler :: $session->create('MTrans');

		$this->currTrans->setName($attributes['name']);
		//$this->currTrans->setType($attributes['type']);
		
		switch ($attributes['type']) {
			case 'TYPE_FIRE':case '0':
				$this->currTrans->setType(0);
				break;
			
			case 'TYPE_AUTO_SYSTEM':case '1':
				$this->currTrans->setType(1);
				break;
			
			case 'TYPE_AUTO_AGENT':case '2':
				$this->currTrans->setType(2);
				break;
				
			case 'TYPE_AUTO_PROCESS':case '3':
				$this->currTrans->setType(3);
				break;
				
			case 'TYPE_TIME':case '4':
				$this->currTrans->setType(4);
				break;
		
			default:
				throw new Exception('tipo de trans desconocido, transName : ',$attributes['name']);
		}
		
		
		
		$this->currTrans->setTime($attributes['time']);

		$transList = & $this->network->getTransList();
		$transList[] = $this->currTrans;

		if (isset ($this->nodesByName[$this->currTrans->getName()])) {
			throw new Exception("Duplicated name " . $this->currTrans->getName());
		}

		$this->nodesByName[$this->currTrans->getName()] = & $this->currTrans;
	}

	private function arcBeg(& $parser, $tag, $attributes) {
		if (!isset ($this->nodesByName[$attributes['src']])) {
			throw new Exception("src node not found");
		}
		if (!isset ($this->nodesByName[$attributes['tgt']])) {
			throw new Exception("tgt node not found");
		}

		$src = & $this->nodesByName[$attributes['src']];
		$tgt = & $this->nodesByName[$attributes['tgt']];
		$multiplicity = $attributes['multiplicity'];

		$place = NULL;
		$trans = NULL;

		$direction = NULL;
		
//		echo "<br> red ", $this->network;

		if (BaseHandler :: $session->getClass($src) == 'MPlace') {
			$place = & $src;
			$trans = & $tgt;

			$direction = MArc :: $DIRECTION_PLACE_TO_TRANS;
		} else {
			$place = & $tgt;
			$trans = & $src;

			$direction = MArc :: $DIRECTION_TRANS_TO_PLACE;
		}
		


		$arc = & BaseHandler :: $session->create('MArc');
		$arc->setDirection($direction);

		$arc->setPlaceRef($place);

		$arc->setTransRef($trans);
		$arc->multiplicity = $multiplicity;
		$this->network->arcList[] = $arc;
	}

	private function classEnd(& $parser, $tag) {
		$this->currTrans->setClass($this->text);
	}

	private function methodClassEnd(& $parser, $tag) {
		$this->currTrans->setMethodClass($this->text);
	}



	private function methodsEnd(& $parser, $tag) {
		$this->currTrans->setMethods($this->text);
	}
	

	private function captionEnd(& $parser, $tag) {
		$this->currTrans->setCaption($this->text);
	}

	private function roleEnd(& $parser, $tag) {
		
		if ($this->currTrans->getType() == MTrans :: $TYPE_AUTO_AGENT || $this->currTrans->getType() == MTrans :: $TYPE_AUTO_PROCESS ) {
			throw new Exception("Auto trans can't have a role: " . $this->currTrans->getName());
		}

		$query = 'FROM MRole AS r WHERE r.name = ?';

		$role = BaseHandler :: $session->find($query, $this->text);

		if ($role == NULL) {
			throw new Exception("Role not found: " . $this->text);
		}

		$role = $role[0];

		$this->currTrans->setRoleRef($role);
	}

	// ----------------------------------------
	// BaseHandler Methods
	// ----------------------------------------

	public function startElement(& $parser, $tag, $attributes) {
		parent :: startElement($parser, $tag, $attributes);

		switch ($tag) {
			case 'network' :
				$this->networkBeg($parser, $tag, $attributes);
				break;
			case 'place' :
				$this->placeBeg($parser, $tag, $attributes);
				break;
			case 'trans' :
				$this->transBeg($parser, $tag, $attributes);
				break;
			case 'edge' :
				$this->arcBeg($parser, $tag, $attributes);
				break;
		}
	}

	public function endElement(& $parser, $tag) {
		parent :: endElement(& $parser, $tag);

		switch ($tag) {
			case 'methods' :
				$this->methodsEnd($parser, $tag);
				break;
			case 'role' :
				$this->roleEnd($parser, $tag);
				break;
			case 'caption' :
				$this->captionEnd($parser, $tag);
				break;
			case 'class' :
				$this->classEnd($parser, $tag);
				break;
			case 'methodClass' :
				$this->methodClassEnd($parser, $tag);
				break;
			
		}
	}

	// ----------------------------------------
	// Props Methods
	// ----------------------------------------
	/**
	 * @return MNetwork
	 */
	public function & getNetwork() {
		return $this->network;
	}
	/**
	 * @return array
	 */
	public function & getNodesByName() {
		return $this->nodesByName;
	}
}
?>
